package sql.parser;

import com.google.common.collect.Lists;
import sql.lexer.SQLLexer;

import java.util.List;

public class InsertParser  extends SyntaxJudge {
    private InsertSyntax insertSyntax = new InsertSyntax();

    public InsertParser(SQLLexer lexer) {
        super(lexer);
    }

    public InsertSyntax parse() {
        this.nextToken();
        if(sql() && this.isEnd()) {
            return insertSyntax;
        } else {
            return null;
        }
    }

    private boolean item(List<String> result) {
        if(isElement(this.getSyntaxType())) {
            result.add(this.getStrToken());
            nextToken();
            return true;
        } else {
            return false;
        }
    }

    private boolean comma() {
        if(this.getSyntaxType() == SyntaxType.Comma) {
            nextToken();
            return true;
        } else {
            return false;
        }
    }

    private boolean itemsTail(List<String> result) {
        if(comma()) {
            if(!item(result)) {
                return false;
            } else {
                return itemsTail(result);
            }
        } else if(this.getSyntaxType() == SyntaxType.BracketEnd) {
            nextToken();
            return true;
        } else {
            return false;
        }
    }

    private boolean items(List<String> result) {
        if(this.getSyntaxType() == SyntaxType.BracketStart) {
            nextToken();
            if(!item(result)) {
                return false;
            } else {
                return itemsTail(result);
            }
        } else {
            return false;
        }
    }

    private boolean valuesList() {
        List<String> values = Lists.newArrayList();
        if(!items(values)) {
            return false;
        } else {
            insertSyntax.getValues().add(values);
            return valuesListTail();
        }
    }

    private boolean valuesListTail() {
        if(comma()) {
            List<String> values = Lists.newArrayList();
            if(!items(values)) {
                return false;
            } else {
                insertSyntax.getValues().add(values);
                return valuesListTail();
            }
        } else if(this.isEnd()) {
            return true;
        } else {
            return false;
        }
    }

    private boolean sql() {
        if(this.getSyntaxType() == SyntaxType.Insert) {
            this.nextToken();
            if(this.getSyntaxType() == SyntaxType.Into) {
                this.nextToken();
                if(this.getSyntaxType() == SyntaxType.Identifier) {
                    insertSyntax.setTable(this.getStrToken());
                    nextToken();
                    List<String> columns = Lists.newArrayList();
                    if(!this.items(columns)) {
                        return false;
                    } else {
                        insertSyntax.setColumns(columns);
                        if(this.getSyntaxType() == SyntaxType.Values) {
                            nextToken();
                            if(!valuesList()) {
                                return false;
                            } else {
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }
}
